package com.cqapp.widget.ui.location;

import android.app.Dialog;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.Circle;
import com.amap.api.maps.model.CircleOptions;

import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.maps.model.animation.Animation; //不知道干啥的Animation，先留着吧
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.cqapp.activity.MainActivity;
import com.cqapp.util.LoadingDialog.WeiboDialogUtils;
import com.cqapp.util.UsersAssessment;
import com.cqapp.widget.R;

import java.util.Vector;

import static android.widget.Button.*;


public class LocationFragment extends Fragment implements LocationSource,
                                                          AMapLocationListener,
                                                          AMap.OnMapTouchListener,
                                                          AMap.OnMapClickListener,
                                                          AMap.OnMapLongClickListener,
                                                          AMap.OnCameraChangeListener,
                                                          GeocodeSearch.OnGeocodeSearchListener,
                                                          Animation.AnimationListener,
                                                          OnClickListener,
                                                          RadioGroup.OnCheckedChangeListener{

    //存放相对应需要的数据，fragment所需要的控件
    private LocationViewModel locationViewModel;

    // 定位相关
    private LocationSource.OnLocationChangedListener mListener = null; //监听地图的Listener
    private AMapLocationClient mlocationClient = null;                 //定位服务
    private AMapLocationClientOption mLocationOption = null;           //地址选择器，配合定位服务使用
    private static LatLng mNowLoc;  // 当前位置

    // 地图相关
    private static AMap mAmap = null;        //地图控制器
    private MapView mMapView = null;         //地图视图
    private UiSettings mUiSettings = null;   //地图界面的UI设置
    private static float mZoom = 16;  // 视图缩放级别

    // 信息检索相关
    private GeocodeSearch mGeocoderSearch = null;// 逆地理编码

    // 手指触碰后新建的图标
    private LatLng mNowSel = null;          // 当前手指选择的位置
    public static boolean HasNowSel = false;// 和MainActivity交换数据用的bool
    private static MarkerOptions mNowSelMop = null;     // 当前选择位置的图标生成器
    private static Marker mNowSelMarker = null ;        // 当前选择位置的图标
    private String mNowSelStr = null;

    // 一些别的成员属性
    private static Circle mCircle200 = null;
    private static Circle mCircle100 = null;
    private static Circle mCircle50 = null;
    private static String TAG = "LocationFragment";//当前类名
    private static boolean  isvisible = false;    // 是否显示信息栏
    private Dialog mWeiboDialog;  // Loading显示
    private View mRoot = null;    // 根元素，用来FindByID

    // 菜单栏
    private TextView mTextView;// Text视图
    private static ConstraintLayout mConstraintLayout;  // 菜单栏界面
    private static ConstraintLayout mConstraintLayout2; // 透明界面

    // 颜色
    private static int mFillcolor = Color.argb(40, 105,192,255);
    private static int mStrokecolor = Color.argb(70, 105,192,255);

    // 界面上的各种元件
    private Button mChooseYes = null;       // 确定保存
    private Button mChooseNo = null;        // 取消保存
    private EditText mAddressName = null;  // 店铺名
    private EditText mAssessText = null;   // 店铺评价
    private RadioGroup mType_radiogroup = null; // 单选框


    // 进行临时存储的数据
    private static Vector<UsersAssessment> mUserAssessments; // 用户所记录的反馈
    private String mTag = "0";


    /**
     * 初始化Fragment
     */
    public View onCreateView(@NonNull LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        locationViewModel = ViewModelProviders.of(this).get(LocationViewModel.class);
         mRoot = inflater.inflate(R.layout.fragment_location, container, false);

        // 获取地图控件引用
        mMapView =  mRoot.findViewById(R.id.map);
        mConstraintLayout = mRoot.findViewById(R.id.information_panel);  //信息栏的面板
        mConstraintLayout2 = mRoot.findViewById(R.id.information_panel2);//透明栏的面板

        // 在activity执行onCreate时执行mMapView.onCreate(savedInstanceState)，创建地图
        mMapView.onCreate(savedInstanceState);

        //初始化Map
        initMap();

        //初始化逆编码对象
        mGeocoderSearch = new GeocodeSearch(MainActivity.mMainContext);
        mGeocoderSearch.setOnGeocodeSearchListener(this);

        // 重绘所有图
        ReDraw();

        // 初始化所有元件
        init();

        return mRoot;
    }

    public void init()
    {
        // 初始化监听事件
        mRoot.findViewById(R.id.ChooseYes).setOnClickListener(this);
        mRoot.findViewById(R.id.ChooseNo).setOnClickListener(this);
        mAddressName = mRoot.findViewById(R.id.AddressName);mAddressName.setOnClickListener(this);
        mAssessText = mRoot.findViewById(R.id.AssessText);mAssessText.setOnClickListener(this);
        mType_radiogroup =  mRoot.findViewById(R.id.type_radiogroup);mType_radiogroup.setOnCheckedChangeListener(this);

        // 初始化临时存储的数据
        mUserAssessments = new Vector<UsersAssessment>();

    }

    /**
     * 初始化mAmap对象
     */
    private void initMap(){

        if (mAmap == null) {
            mAmap = mMapView.getMap();
            setUpMap();
        }
        //设置地图的放缩级别
        mAmap.moveCamera(CameraUpdateFactory.zoomTo(mZoom));
        //实例化UiSettings类对象
        mUiSettings = mAmap.getUiSettings();
        //显示指南针
        mUiSettings.setCompassEnabled(true);
        //显示比例尺
        mUiSettings.setScaleControlsEnabled(true);
        //设置缩放按钮
        mUiSettings.setZoomControlsEnabled(true);
    }


    /**
     * 设置一些mAmap的属性
     */
    private void setUpMap() {
        // 使用默认定位点
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        // 使用指定图标的定位点
        // myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.red_marker));

        // 设置定位点自带的圆圈
        myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));// 设置圆形的填充颜色,alpha = 0为透明
        myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));    // 设置圆形的边框颜色,alpha = 0为透明
        // myLocationStyle.strokeWidth(1.0f);// 设置圆形的边框粗细

        // 设置连续定位模式下的定位间隔，只在连续定位模式下生效，单次定位模式下不会生效。单位为毫秒。
        // myLocationStyle.interval(2000);
        // 蓝点定位模式：定位一次，且将视角移动到地图中心点。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);

        mAmap.setMyLocationStyle(myLocationStyle);
        mAmap.setOnMapClickListener(this);      //设置按下时的监听
        mAmap.setOnMapLongClickListener(this);  //设置长摁时的监听
        mAmap.setOnCameraChangeListener(this);  //设置地图变化时的监听

        // mAmap.setOnMapTouchListener(this); //设置触摸时的监听 目前为止没用过

        mAmap.setLocationSource(this);// 设置定位资源。如果不设置此定位资源则定位按钮不可点击。并且实现activate激活定位,停止定位的回调方法
        mAmap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        mAmap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false

    }

    /**
     * 定位成功后回调函数
     * @param aMapLocation //地址选择器
     */
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (mListener != null && aMapLocation != null) {
            if (aMapLocation != null && aMapLocation.getErrorCode() == 0) {

                // Log.d("经纬度位置", "维度"+aMapLocation.getLatitude()+ "经度"+ aMapLocation.getLongitude()+"位置描述"+aMapLocation.getAddress());

                //获得当前坐标
                mNowLoc =  new LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude());

                // 清空所有画图,再重新画一遍
                ReDraw();

                // final Marker marker = mAmap.addMarker(new MarkerOptions().position(latLng).title("奶茶店").snippet("据您"+ AMapUtils.calculateLineDistance(latLng,mNowLoc)+"米"));
                // drawCircle(new LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude()));

                mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点
            } else {
                String errText = "定位失败," + aMapLocation.getErrorCode()+ ": " + aMapLocation.getErrorInfo();
                System.out.println(errText);
                Toast.makeText(MainActivity.mMainContext, "定位失败,请检查是否打开GPS", Toast.LENGTH_SHORT).show();
            }

        }
    }

    /**
     * 重绘所有图案
     */
    private static void ReDraw()
    {
        // 删除当前选择的位置，不然会和下面的绘制冲突
        if(mNowSelMarker != null)
            mNowSelMarker.remove();

        // 绘制当前选择的位置
        if(HasNowSel)
            mNowSelMarker = mAmap.addMarker(mNowSelMop);

        // 绘制圆形
        DrawCircle(mNowLoc);

    }


    /**
     * 将视图还原到当前位置
     */
    public static void Back2NowLoc()
    {
        // 已经没有选择点了
        HasNowSel = false;
        // 重新绘制
        ReDraw();
        // 相机移动到当前位置
        MoveCamera(mNowLoc,mZoom);
        // 关闭信息框
        isvisible = false;
        ShowOrHide(new LatLng(0,0));

    }

    /**
     * 绘制圆圈
     * @param latLng 坐标信息
     */
    public static void DrawCircle(LatLng latLng) {
        String color = "#26b637";
        StringBuilder sb = new StringBuilder(color);// 构造一个StringBuilder对象
        sb.insert(1, "50");// 在指定的位置10，插入指定的字符串

        // 当初始化之后再绘制时，都要先清空一次再绘制
         if(mCircle200 != null)
             mCircle200.remove();
        // 执行绘制操作
        {
            mCircle200 = mAmap.addCircle(new CircleOptions()
                    .center(latLng)
                    .radius(200)
                    .fillColor(mFillcolor)
                    .strokeColor(mStrokecolor)
                    .strokeWidth(5));
        }

        // 同理
        if(mCircle100 != null)
            mCircle100.remove();

        {
            mCircle100 = mAmap.addCircle(new CircleOptions()
                    .center(latLng)
                    .radius(100)
                    .fillColor(mFillcolor)
                    .strokeColor(mStrokecolor)
                    .strokeWidth(5));
        }

        // 同理
        if(mCircle50 != null)
            mCircle50.remove();

        {
            mCircle50 = mAmap.addCircle(new CircleOptions()
                    .center(latLng)
                    .radius(50)
                    .fillColor(mFillcolor)
                    .strokeColor(mStrokecolor)
                    .strokeWidth(5));
        }

    }

    /***
     * 按下事件里面处理显示信息的面板
     * @param latLng 坐标信息
     */
    @Override
    public void onMapClick(LatLng latLng) {
        Log.d(TAG, "onMapClick: 被按下");
        // bottomNavigationView.setVisibility(View.GONE);

        // 关闭菜单框
        isvisible = false;
        ShowOrHide(latLng);
    }

    /**
     * 对长按地图事件回调
     * @param latLng 坐标信息
     */
    @Override
    public void onMapLongClick(LatLng latLng) {
        Log.d(TAG, "onMapLongClick: 长摁");
        mNowSel = latLng;
        HasNowSel = true;

        // 逆地理编码 返回该点的信息
        getAddress(new LatLonPoint(latLng.latitude,latLng.longitude));

        // 视情况新建对象
        if (mNowSelMop == null)
            mNowSelMop = new MarkerOptions();

        // 显示loading框
        mWeiboDialog = WeiboDialogUtils.createLoadingDialog(MainActivity.mMainContext, "加载中...");

        isvisible = true;
        // 显示框框
        ShowOrHide(latLng);
    }

    /**
     * 显示信息填写框
     * @param latLng 坐标信息
     */
    public static void ShowOrHide(LatLng latLng)
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (isvisible){
                    Message msg =new Message();
                    msg.what = 1;
                    msg.obj = latLng;
                    handler.sendMessage(msg);
                    isvisible = !isvisible;
                }
                else{
                    Message msg =new Message();
                    msg.what = 2;
                    handler.sendMessage(msg);
                    isvisible = !isvisible;
                }
            }
        }).start();
    }

    /**
     * 移动相机
     * @param latLng  坐标信息
     */
    public static void MoveCamera(LatLng latLng,float Zoom)
    {
        CameraUpdate mCameraUpdate = CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(latLng.latitude,latLng.longitude),// 地理坐标
                Zoom,0,0));// 缩放级别、角度、不知道
        // 移动当前视图到新的中心
        mAmap.animateCamera(mCameraUpdate);
        // 无动画版
        // mAmap.moveCamera(CameraUpdateFactory.changeLatLng(latLng));

    }

    /**
     * 图标生成器
     * @param latLng  坐标信息
     * @param title   标题信息
     */
    public void SetMarkerOption(LatLng latLng,String title,String tag)
    {
        // 设置Marker位置
        mNowSelMop.position(latLng);
        // 设置弹出的标签
        System.out.println("先设置好标签");
        mNowSelMop.title(title).snippet("据您"+ AMapUtils.calculateLineDistance(latLng,mNowLoc)+"米");
        //设置Marker可拖动
        mNowSelMop.draggable(false);
        // 设置图标
        switch (tag)
        {
            case "0":
                mNowSelMop.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(),R.drawable.milktea)));
                break;
            case "1":
                mNowSelMop.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(),R.drawable.cake)));
                break;
            case "2":
                mNowSelMop.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(),R.drawable.westenfood)));
                break;
            case "3":
                mNowSelMop.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(),R.drawable.fastfood)));
                break;
            default:
                mNowSelMop.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(),R.drawable.redmarker)));
                break;

        }

        // 将Marker设置为贴地显示，可以双指下拉地图查看效果
        mNowSelMop.setFlat(false);

    }

    /**
     * 调用逆编码，得到当前坐标点的POI信息
     * @param latLonPoint 和
     */
    public void getAddress(LatLonPoint latLonPoint) {
        // 第二参数表示范围200米，第三个参数表示是火系坐标系还是GPS原生坐标系
        RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP);
        mGeocoderSearch.getFromLocationAsyn(query);// 设置同步逆地理编码请求
    }

    /**
     * 逆地理编码回调（坐标转地址）
     * @param result  可以解析的对象
     * @param rCode   结果状态码
     */
    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
        if (rCode == 1000) {
            if (result != null && result.getRegeocodeAddress() != null && result.getRegeocodeAddress().getFormatAddress() != null) {
                String addressName = result.getRegeocodeAddress().getFormatAddress(); // 逆转地里编码不是每次都可以得到对应地图上的opi
                System.out.println("逆地理编码回调  得到的地址：" + addressName);
                mNowSelStr = addressName;
                // 添加图标信息
                SetMarkerOption(mNowSel,addressName,"");
                // 移动摄像机
                MoveCamera(mNowSel,18);
                // 重新绘制
                ReDraw();
            } else {
                System.out.println("没有结果");
                Toast.makeText(MainActivity.mMainContext, "该地无查询结果", Toast.LENGTH_SHORT).show();
            }
        } else if (rCode == 27) {
            System.out.println("网络错误");
            Toast.makeText(MainActivity.mMainContext, "网络错误,请检查是否连接网络", Toast.LENGTH_SHORT).show();

        } else {
            System.out.println("未知错误");
            Toast.makeText(MainActivity.mMainContext, "未知错误,请联系管理员", Toast.LENGTH_SHORT).show();
        }
        // 关闭Loading框
        WeiboDialogUtils.closeDialog(mWeiboDialog);

    }

    /**
     * 地理编码回调（地址转坐标）
     * @param geocodeResult   可以解析的对象
     * @param rCode   结果状态码
     */
    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int rCode) {
        // 暂时不用实现
    }

    /**
     * 触摸屏幕的监听
     * @param motionEvent
     */
    @Override
    public void onTouch(MotionEvent motionEvent) {
        // 暂时不用实现
        // Log.d(TAG, "onTouch: 被按下");
    }

    /**
     * 激活定位
     * @param onLocationChangedListener 地址监听器
     */
    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (mlocationClient == null) {
            //初始化定位
            mlocationClient = new AMapLocationClient(getContext());
            //初始化定位参数
            mLocationOption = new AMapLocationClientOption();
            //设置定位回调监听
            mlocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mlocationClient.startLocation();//启动定位
        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

    /**
     * 消息传递，用来打开菜单面板的
     */
    private static Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 1:
                    // 信息面板出现
                    LatLng latLng = (LatLng) msg.obj;
                    mConstraintLayout2.setVisibility(View.VISIBLE);
                    mConstraintLayout.setVisibility(View.VISIBLE);
                    // mTextView.setVisibility(View.VISIBLE);
                    // mTextView.setText("位置为："+latLng.toString());
                    break;
                case 2:
                    // 信息面部隐藏
                    mConstraintLayout.setVisibility(View.GONE);
                    mConstraintLayout2.setVisibility(View.GONE);
                    // mTextView.setVisibility(View.GONE);
            }
        }
    };

    /**
     * 什么都可以监听的监听器
     * @param view
     */
    @Override
    public void onClick(View view) {
        switch (view.getId())
        {
            // 取消记录新的点
            case R.id.ChooseNo:
                isvisible = false;
                ShowOrHide(new LatLng(0,0));
                Back2NowLoc();
                mAddressName.setHint("请输入店铺名");
                mAssessText.setHint("请输入评价");
                break;

            // 选择记录新的点
            case R.id.ChooseYes:
                String AddressName = mAddressName.getText().toString();
                String AssessText = mAssessText.getText().toString();
                if(AddressName.equals(""))
                {
                    Toast.makeText(MainActivity.mMainContext, "请输入店铺名字", Toast.LENGTH_SHORT).show();
                }
                else if(AssessText.equals(""))
                {
                    Toast.makeText(MainActivity.mMainContext, "请输入评价信息", Toast.LENGTH_SHORT).show();
                }
                else
                {
                    SetMarkerOption(mNowSel,AddressName+"\n"+AssessText,mTag);
                    mUserAssessments.add(new UsersAssessment(AddressName,AssessText,mTag,mNowSel));
                    mUserAssessments.get(mUserAssessments.size()-1).setmMarker(mAmap.addMarker(mNowSelMop));
                    mAddressName.setText("");
                    mAssessText.setText("");
                    mAddressName.setHint("请输入店铺名");
                    mAssessText.setHint("请输入评价");
                    mNowSelMarker.remove();
                    // 关闭信息框
                    isvisible = false;
                    ShowOrHide(new LatLng(0,0));

                }

                break;

            // 当输入店铺信息的时候
            case R.id.AddressName:
                mAddressName.setHint(null);
                break;

            // 当输入店铺点评的时候
            case R.id.AssessText:
                mAssessText.setHint(null);
                break;
        }

    }

    /**
     * 什么都可以监听的监听器
     * @param radioGroup radio组
     * @param i  被唤醒的编号
     */
    @Override
    public void onCheckedChanged(RadioGroup radioGroup, int i) {
        // System.out.println("i的值"+i);
        // System.out.println("被唤醒的对象的编号"+radioGroup.getCheckedRadioButtonId());
        // 上面这俩是一样的
        mTag = (String)mRoot.findViewById(i).getTag();

    }

    /**
     * 视图大小变更的监听
     */
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        // mZoom = mAmap.getCameraPosition().zoom;
        // System.out.println("地图变化"+mAmap.getCameraPosition().zoom);
    }

    /**
     * 视图变更结束后的监听
     */
    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        // 暂时不用实现
    }

    /**
     * 不知道是什么的动画开启
     */
    @Override
    public void onAnimationStart()
    {
        // 暂时不用实现
    }

    /**
     * 不知道是什么的动画结束
     */
    @Override
    public void onAnimationEnd()
    {
        // 暂时不用实现
    }



}
